import Cocoa

/*
 用来指定某个实例可能没有值，看到可空类型时，你会知道该实例一定：要么有值，并且已经可用，要么没有值，如果一个实例没有值，就称其为nil。
 一个可能为nil的实例应该被声明为可空类型。这意味着如果一个实例没有被声明为可空类型，它就不可能是nil。
 */
//1.声明可空类型
var errorCodeString:String?
errorCodeString = "404"
print(errorCodeString)
//print(errorCodeString!)   //强制展开输出
//print(errorCodeString ?? "ss")

if errorCodeString != nil {
    let theError = errorCodeString! //！是强制展开的意思，直接取可空类型中的值404
    print(theError)
    
}


//2.可空实例绑定
if let theError1 = errorCodeString {
    print(theError1)
}
/*
 如果可空类型有值，那么就会有一个临时常量；如果条件计算为真，执行代码块中就可以使用这个常量，且不再需要强制展开可空类型了。
 */



//3.嵌套的可空实例绑定
if let  theError2 = errorCodeString
{
    if let errorCodeInteger = Int(theError2)
    {
        print("\(theError2):\(errorCodeInteger)")
    }
}


//4.展开多个可空类型
if let theError3 = errorCodeString,let errorCodeInteger = Int(theError3)    //任何一个返回nil，条件语句不会执行
{
    print("\(theError3):\(errorCodeInteger)")
}

//5.可空实例绑定和额外的检查
if let theError4 = errorCodeString,let errorCodeInteger = Int(theError4),errorCodeInteger == 404
{
    print("\(theError4):\(errorCodeInteger)")
}

////6.隐式展开可空类型(作废)
//var errorCodeString1:String!
//errorCodeString1 = "404"
//print(errorCodeString1)


//7.可空链式调用
var errorCodeString3:String?
errorCodeString3 = "404"
var errorDescription:String?
if let theError = errorCodeString3,let errorCodeInteger = Int(theError),errorCodeInteger == 404
{
    errorDescription = "\(errorCodeInteger + 200):resource was not found"
}
var upCaseErrorDescription = errorDescription?.uppercased() //？表示这行代码开启了可空链式调用的过程。如果errorDescription没有值，返回nil给upCaseErrorDescription
errorDescription



//8.原地修改可空实例
upCaseErrorDescription?.append("PLEASE TRY AGAIN")
upCaseErrorDescription
/*
 如果可空实例有值，就更新，没有，就什么都不做
 */


//9.nil合并运算符
var  description = ""
if let errorDescription = errorDescription
{
    description = errorDescription;
}
else
{
    description = "No error"
}
// 另外一种写法
let description1 = errorDescription ?? "error"
/*
 ??左边必须为可空实例，右边必须是非可空的同类型实例，如果左边的实例为nil,那么??会返回右边的值
 */
